#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/6/16 10:04
# @Author  : fuchen'en
# @Description:

import pika
import uuid


class FibonacciRpcClient(object):

    def __init__(self):
        # RabbitMQ用户名/密码
        credentials = pika.PlainCredentials('test', 'test123')
        # RabbitMQ连接参数
        parameters = pika.ConnectionParameters(host='10.0.20.66',
                                               port='5672',
                                               virtual_host='/',
                                               credentials=credentials)
        # 建立连接
        self.connection = pika.BlockingConnection(parameters)

        # 获取通道
        self.channel = self.connection.channel()

        # 声明专用队列，队列名称让RabbitMQ随机生成，用于保存回调函数
        result = self.channel.queue_declare(queue='', exclusive=True)
        self.callback_queue = result.method.queue

        # 客户端处理消息响应，回应服务器采用auto_ack自动确认
        self.channel.basic_consume(queue=self.callback_queue,
                                   on_message_callback=self.on_response,
                                   auto_ack=True)

    # 匹配对应的correlation_id，只处理匹配的，不匹配直接丢弃
    def on_response(self, ch, method, props, body):
        if self.corr_id == props.correlation_id:
            self.response = body

    # client发起请求，每次都生成一个uuid，用来标记请求
    def call(self, n):
        self.response = None
        self.corr_id = str(uuid.uuid4())
        # 请求发送到rpc_queue队列，响应从callback_queue队列中获取，并且要匹配对应的correlation_id
        self.channel.basic_publish(exchange='',
                                   routing_key='rpc_queue',
                                   properties=pika.BasicProperties(reply_to=self.callback_queue,
                                                                   correlation_id=self.corr_id),
                                   body=str(n))
        while self.response is None:
            self.connection.process_data_events()
        return int(self.response)


fibonacci_rpc = FibonacciRpcClient()

print(' [x] Requesting fib(20)')
response = fibonacci_rpc.call(20)
print(' [.] Got {!r}'.format(response))
